home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Interapplication Communication / MenuScripter 4.0 / Sources / MSAECreate.c < prev    next >
Encoding:
Text File  |  1996-07-09  |  11.4 KB  |  435 lines  |  [TEXT/CWIE]

  1. // MSAECreate.c
  2. //
  3. // Original version by Jon Lansdell and Nigel Humphreys.
  4. // 4.0 and 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1996, all rights reserved.
  6.  
  7. /*
  8.     14-Nov-95 : GS : Removed unused local varibale in DoNewElement().
  9. */
  10.  
  11. #include "MSAECreate.h"
  12.  
  13. #include "MSGlobals.h"
  14. #include "MSWindow.h"
  15. #include "MSAEUtils.h"
  16. #include "MSAETextUtils.h"
  17. #include "MSAppleEvents.h"
  18.  
  19. #include "MSAccessors.h"
  20. #include "MSAERecording.h"
  21. #include "MSAESelect.h"
  22. #include "MSAEWindowUtils.h"
  23. #include "MSAESetData.h"
  24.  
  25.  
  26. #pragma segment AppleEvent
  27.  
  28.  
  29. // ------------------------------------------------------------------------
  30. //    Name:         DoNewElement
  31. //    Purpose:    Handles the NewElement AppleEvent. Creates windows and
  32. //                text.
  33. // ------------------------------------------------------------------------
  34.  
  35. pascal OSErr    DoNewElement(const AppleEvent    *theAppleEvent,
  36.                                     AppleEvent    *reply, 
  37.                                     long        handlerRefCon)
  38. {
  39. #ifdef __MWERKS__
  40.     #pragma unused (handlerRefCon)
  41. #endif
  42.  
  43.     DescType    returnedType,
  44.                 newElemClass;
  45.     Size        actualSize;
  46.     AEDesc        dataDesc = {typeNull, NULL},
  47.                 insertHereDesc = {typeNull, NULL},
  48.                 propertyDesc = {typeNull, NULL},
  49.                 resultDesc = {typeNull, NULL};
  50.     OSErr       ignoreErr,
  51.                 err;
  52.         
  53.     err = AEGetParamPtr(theAppleEvent, keyAEObjectClass, typeType,
  54.                             &returnedType, (Ptr)&newElemClass, sizeof(newElemClass), &actualSize);
  55.     if (noErr != err) goto done;        // We have to know what object to create
  56.     
  57.         // Get optional parameters
  58.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &dataDesc);
  59.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEInsertHere, typeWildCard, &insertHereDesc);
  60.     ignoreErr = AEGetParamDesc(theAppleEvent, keyAEPropData, typeWildCard, &propertyDesc);
  61.             
  62.         // check for missing required parameters
  63.     err = GotRequiredParams(theAppleEvent);
  64.     if (noErr != err) goto done;
  65.  
  66.     switch (newElemClass)
  67.     {
  68.         case cWindow:
  69.         case cDocument:
  70.             err = CreateDocument(&dataDesc, &insertHereDesc, &propertyDesc, &resultDesc);
  71.             break;
  72.             
  73.         case cChar:
  74.         case cText:
  75.         case cWord:
  76.         case cParagraph:
  77.             err = CreateText(newElemClass, &dataDesc, &insertHereDesc, &propertyDesc, &resultDesc);
  78.             break;
  79.             
  80.         default:
  81.             err = errAEWrongDataType;
  82.     }
  83.     
  84.     err = AddResultToReply(&resultDesc, reply, err);
  85.  
  86. done:            
  87.     if (dataDesc.dataHandle) 
  88.         AEDisposeDesc(&dataDesc);
  89.     if (insertHereDesc.dataHandle) 
  90.         AEDisposeDesc(&insertHereDesc);
  91.     if (propertyDesc.dataHandle) 
  92.         AEDisposeDesc(&propertyDesc);
  93.     if (resultDesc.dataHandle) 
  94.         AEDisposeDesc(&resultDesc);
  95.         
  96.     return(err);
  97. } // DoNewElement
  98.  
  99.  
  100. OSErr    CreateDocument(AEDesc* dataDesc, AEDesc* insertHereDesc,
  101.                                                 AEDesc* propertyDesc, AEDesc* result)
  102. {
  103.     AEDesc        insertDesc = {typeNull, NULL};
  104.     DescType     insertType;
  105.     DPtr        docPtr;
  106.     WindowPtr    behindWindow;
  107.     OSErr        err;
  108.  
  109.      err = GetInsertDescFromInsertHere(insertHereDesc, &insertDesc, &insertType);
  110.     if (noErr != err) goto done;
  111.     
  112.     err = GetBehindWindow(&insertDesc, insertType, &behindWindow);
  113.     if (noErr != err) goto done;
  114.     
  115.     docPtr = NewDocument(false, behindWindow);
  116.  
  117.     if (! docPtr)
  118.     {
  119.         err = errAENoSuchObject;
  120.         goto done;
  121.     }
  122.  
  123.     if (propertyDesc->dataHandle)
  124.         err = SetDocumentPropertyRecord(docPtr->theWindow, propertyDesc);
  125.     if (noErr != err) goto done;
  126.  
  127.     if ( dataDesc->dataHandle && dataDesc->descriptorType != typeAEList )
  128.     {
  129.         err = SetDocumentData(docPtr->theWindow, dataDesc);
  130.         docPtr->dirty = true;
  131.     }
  132.     else
  133.         docPtr->dirty = false;
  134.     if (noErr != err) goto done;
  135.  
  136.     ShowMSWindow(docPtr->theWindow);
  137.     err = MakeDocumentObj(docPtr->theWindow, result);
  138.  
  139. done:
  140.     (void)AEDisposeDesc(&insertDesc);
  141.  
  142.     return(err);
  143. }
  144.  
  145. OSErr    GetBehindWindow(AEDesc* insertDesc, DescType insertType, WindowPtr* behindWindow)
  146. {
  147.     AEDesc            windowDesc = {typeNull, NULL};
  148.     WindowToken        aWindowToken;
  149.     Size            actualSize;
  150.     short            index;
  151.     OSErr            err;
  152.  
  153.     if (typeNull == insertDesc->descriptorType)
  154.     {
  155.         *behindWindow = (WindowPtr) -1L;
  156.         return(noErr);
  157.     }
  158.     
  159.     err = AECoerceDesc(insertDesc, typeMyWndw, &windowDesc);
  160.     if (noErr != err) goto done;
  161.  
  162.     GetRawDataFromDescriptor(&windowDesc, (Ptr)&aWindowToken,
  163.                                     sizeof(aWindowToken), &actualSize);
  164.  
  165.     switch (insertType)
  166.     {
  167.         case kAEBeginning:
  168.             *behindWindow = (WindowPtr) -1L;
  169.             break;
  170.     
  171.         case kAEEnd:
  172.             *behindWindow = NULL;
  173.             break;
  174.         
  175.         case kAEBefore:
  176.             index = GetWindowIndex(aWindowToken.tokenWindow);
  177.             if (index > 1)
  178.                 *behindWindow = GetNthWindow(index - 1);
  179.             else
  180.                 *behindWindow = (WindowPtr) -1L;    // Stick at front because no
  181.             break;                                    // windows before that.
  182.         
  183.         case kAEAfter:
  184.             *behindWindow = aWindowToken.tokenWindow;
  185.             break;
  186.         
  187.         case kAEReplace:
  188.         default:
  189.             err = errAEEventFailed;        // We won't allow a new window to replace an existing one
  190.     }
  191.     
  192. done:
  193.     if (windowDesc.dataHandle)
  194.         (void)AEDisposeDesc(&windowDesc);
  195.  
  196.     return(err);
  197. }
  198.  
  199. OSErr    SetDocumentPropertyRecord(WindowPtr theWindow, AEDesc* propertyRecord)
  200. {
  201.     WindowPropToken        aWindowPropToken;
  202.     AEDesc                dataDesc = {typeNull, NULL},
  203.                         propertyDesc = {typeNull, NULL};
  204.     AEKeyword            theAEKeyword;
  205.     long                index;
  206.     OSErr                err;
  207.     
  208.     aWindowPropToken.tokenWindowToken.tokenWindow = theWindow;
  209.                                     
  210.     err = AECountItems(propertyRecord, &index);
  211.     if (noErr != err) goto done;
  212.     
  213.             // Step through each property - creating a window property token AEDesc
  214.             // and letting SetDocumentProperty() do the work.
  215.     for (; index > 0; index--)
  216.     {
  217.         err = AEGetNthDesc(propertyRecord, index, typeWildCard, &theAEKeyword, &dataDesc);
  218.         if (noErr != err) goto done;
  219.  
  220.         aWindowPropToken.tokenProperty = theAEKeyword;
  221.         err = AECreateDesc(typeMyDocumentProp, (Ptr)&aWindowPropToken, 
  222.                                         sizeof(aWindowPropToken), &propertyDesc);
  223.         if (noErr != err) goto done;
  224.         
  225.         err = SetDocumentProperty(&propertyDesc, &dataDesc);
  226.         if (noErr != err) goto done;
  227.         
  228.         (void)AEDisposeDesc(&dataDesc);
  229.         (void)AEDisposeDesc(&propertyDesc);
  230.     }
  231.     
  232. done:
  233.     (void)AEDisposeDesc(&dataDesc);
  234.     (void)AEDisposeDesc(&propertyDesc);
  235.     
  236.     return(err);
  237. }
  238.  
  239. // We'll just assume it's text and put it through as the selection.
  240.  
  241. OSErr    SetDocumentData( WindowPtr theWindow, AEDesc* dataDesc)
  242. {
  243.     WindowPropToken        aPropToken;
  244.     OSErr                err;
  245.     
  246.     aPropToken.tokenWindowToken.tokenWindow = theWindow;
  247.     aPropToken.tokenProperty = pSelection;
  248.     
  249.     err = SetDocumentTokenProperty( &aPropToken, dataDesc );
  250.  
  251.     return err;
  252. }
  253.  
  254.  
  255. OSErr    CreateText(DescType textType, AEDesc* dataDesc, AEDesc* insertHereDesc,
  256.                                                 AEDesc* propertyDesc, AEDesc* result)
  257. {
  258.     AEDesc        insertDesc = {typeNull, NULL};
  259.     DescType     insertType;
  260.     TextToken    anInsertToken;
  261.     short        ignore;
  262.     OSErr        err = noErr;
  263.  
  264.      err = GetInsertDescFromInsertHere(insertHereDesc, &insertDesc, &insertType);
  265.     if (noErr != err) goto done;
  266.     
  267.     if (typeNull == insertType)        // Default to setting the selection in the front window
  268.         err = GetWindowSelection(FrontWindow(), &anInsertToken, &ignore);
  269.     else                            // Otherwise get a selection from the insertDesc
  270.         err = GetInsertToken(&insertDesc, insertType, &anInsertToken);
  271.         
  272.     if (noErr != err) goto done;
  273.     
  274.     err = CreateAtTextToken(textType, dataDesc, &anInsertToken, propertyDesc, result);
  275.  
  276. done:
  277.     if (insertDesc.dataHandle)
  278.         AEDisposeDesc(&insertDesc);
  279.  
  280.     return(err);
  281. }
  282.  
  283. // Get a TextToken for the location of where to insert the text. If the insertType is
  284. // a relative position then work this out. Otherwise just use the insertDesc.
  285.  
  286. OSErr    GetInsertToken(AEDesc* insertDesc, DescType insertType, TextToken* resultToken)
  287. {
  288.     AEDesc        textDesc = {typeNull, NULL};
  289.     TextToken    aTextToken;
  290.     Size        actualSize;
  291.     OSErr        err;
  292.  
  293.     err = AECoerceDesc(insertDesc, typeMyText, &textDesc);
  294.     if (noErr != err) goto done;
  295.  
  296.     GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken,
  297.                                     sizeof(aTextToken), &actualSize);
  298.     resultToken->tokenWindow = aTextToken.tokenWindow;
  299.  
  300.     switch (insertType)
  301.     {
  302.         case kAEBeginning:
  303.         case kAEBefore:
  304.             resultToken->tokenOffset = aTextToken.tokenOffset;
  305.             resultToken->tokenLength = 0;
  306.             break;
  307.     
  308.         case kAEEnd:
  309.         case kAEAfter:
  310.             resultToken->tokenOffset = aTextToken.tokenOffset + aTextToken.tokenLength;
  311.             resultToken->tokenLength = 0;
  312.             break;
  313.         
  314.         case kAEReplace:
  315.         default:            // default is probably some text token to replace
  316.                             // e.g make new word at middle word of document 1 with data "Iris"
  317.                             // It has been coerced to text so it's okay
  318.             resultToken->tokenOffset = aTextToken.tokenOffset;
  319.             resultToken->tokenLength = aTextToken.tokenLength;
  320.             break;
  321.     }
  322.  
  323. done:
  324.     if (textDesc.dataHandle)
  325.         (void)AEDisposeDesc(&textDesc);
  326.     
  327.     return(err);
  328. }
  329.  
  330. // Create text using the dataDesc (which could be text, styled text, etc…) at the
  331. // the location held in the TextToken.
  332. // Properties in the propertyDesc will be applied to the new text.
  333. // Returns an object specifier to the text.
  334.  
  335. OSErr       CreateAtTextToken(DescType textType, const AEDesc* dataDesc, TextToken* theToken,
  336.                                                     AEDesc* propertyDesc, AEDesc* result)
  337. {
  338. #ifdef __MWERKS__
  339.     #pragma unused(textType)
  340. #endif
  341.  
  342.     DPtr        docPtr;
  343.     TextToken    aSelectionToken;
  344.     short        oldLength;
  345.     OSErr        err;
  346.  
  347.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  348.     
  349.     if (! docPtr)
  350.         return(errAENoSuchObject);
  351.  
  352.             // Copy the current selection - so we can restore it after
  353.     err = GetWindowSelection(theToken->tokenWindow, &aSelectionToken, &oldLength);
  354.     if (noErr != err) goto done;
  355.  
  356.             // Set the selection we want to insert the new text into
  357.     err = SelectTextToken(theToken);
  358.     if (noErr != err) goto done;
  359.  
  360.     err = PutStyledTextFromDescIntoTEHandle(dataDesc, docPtr->theText);
  361.     if (noErr != err) goto done;
  362.     
  363.             // Update the selection and get the length of the insertion
  364.     err = UpdateSelectionToken(theToken, &aSelectionToken, oldLength,
  365.                                                         &theToken->tokenLength);
  366.     if (noErr != err) goto done;
  367.     
  368.     // Need to check on token type in here and make what user wanted
  369.     // e.g. make sure a word is a word.
  370.     // Would have to remember to balance token for any chages to TEHandle.
  371.  
  372.     if (propertyDesc->dataHandle)
  373.     {                                    // I doubt we'll handle setting the text property
  374.                                         // or anything that changes the token length… oh well
  375.         err = SetTextPropertyRecord(theToken, propertyDesc);
  376.         if (noErr != err) goto done;
  377.     }
  378.             // Make the returned object
  379.     err = MakeTextObjFromToken(theToken, result);
  380.     
  381. done:
  382.     return(err);
  383. }
  384.  
  385.  
  386. // Take a TextToken and apply the properties in the propertyRecord descriptor
  387. // to the text.
  388. // e.g. make new word at beginning of document 1 with data "Bert" ¬
  389. //                                with properties {size:32, font:"Courier"}
  390. // The with properties part is the property record.
  391.  
  392. OSErr    SetTextPropertyRecord(TextToken* aTextToken, AEDesc* propertyRecord)
  393. {
  394.     TextPropToken        aTextPropToken;
  395.     AEDesc                dataDesc = {typeNull, NULL},
  396.                         propertyDesc = {typeNull, NULL};
  397.     AEKeyword            theAEKeyword;
  398.     long                index;
  399.     OSErr                err;
  400.     
  401.     aTextPropToken.tokenTextToken = *aTextToken;
  402.                                     
  403.     err = AECountItems(propertyRecord, &index);
  404.     if (noErr != err) goto done;
  405.     
  406.             // Step through each property - creating a window property token AEDesc
  407.             // and letting SetWindowProperty() do the work.
  408.     for (; index > 0; index--)
  409.     {
  410.         err = AEGetNthDesc(propertyRecord, index, typeWildCard, &theAEKeyword, &dataDesc);
  411.         if (noErr != err) goto done;
  412.  
  413.         aTextPropToken.tokenProperty = theAEKeyword;
  414.         err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken, 
  415.                                         sizeof(aTextPropToken), &propertyDesc);
  416.         if (noErr != err) goto done;
  417.         
  418.         err = SetTextProperty(&propertyDesc, &dataDesc);
  419.         if (noErr != err) goto done;
  420.         
  421.         if (dataDesc.dataHandle)
  422.             AEDisposeDesc(&dataDesc);
  423.         if (propertyDesc.dataHandle)
  424.             AEDisposeDesc(&propertyDesc);
  425.     }
  426.     
  427. done:
  428.     if (dataDesc.dataHandle)
  429.         AEDisposeDesc(&dataDesc);
  430.     if (propertyDesc.dataHandle)
  431.         AEDisposeDesc(&propertyDesc);
  432.     
  433.     return(err);
  434. }
  435.